using System;
using System.Diagnostics;
using DeviceCommons;
using DeviceCommons.DataHandling;
using DeviceCommons.DeviceMessages.Builders;
using DeviceCommons.DeviceMessages.Enums;
using DeviceCommons.DeviceMessages.Serialization;

namespace DeviceDataGenerator
{
    /// <summary>
    /// 构造器AES模式配置演示程序
    /// </summary>
    public class BuilderAesModeDemo
    {
        public static void RunDemo()
        {
            Console.WriteLine("=== DeviceMessageBuilder AES模式配置演示 ===\n");

            Console.WriteLine("🔧 构造器AES模式配置功能:");
            Console.WriteLine("- WithAesEncryption(password, AesMode): 指定AES模式的加密配置");
            Console.WriteLine("- WithFastAesEncryption(password): 快速模式加密（1000次迭代，启用缓存）");
            Console.WriteLine("- WithSecureAesEncryption(password): 安全模式加密（60000次迭代，禁用缓存）");
            Console.WriteLine("- 向后兼容：原有WithAesEncryption方法保持不变\n");

            var testPassword = "builder-demo-password";

            // 演示1：原有的AES加密方法（向后兼容）
            Console.WriteLine("📋 演示1：原有AES加密方法（向后兼容）");
            DemonstrateBuilderConfiguration("默认AES加密", builder =>
            {
                return builder.WithAesEncryption(testPassword);
            });

            // 演示2：显式配置快速模式
            Console.WriteLine("\n📋 演示2：显式配置快速模式");
            DemonstrateBuilderConfiguration("快速模式", builder =>
            {
                return builder.WithFastAesEncryption(testPassword);
            });

            // 演示3：显式配置安全模式
            Console.WriteLine("\n📋 演示3：显式配置安全模式");
            DemonstrateBuilderConfiguration("安全模式", builder =>
            {
                return builder.WithSecureAesEncryption(testPassword);
            });

            // 演示4：使用重载方法指定模式
            Console.WriteLine("\n📋 演示4：使用重载方法指定模式");
            DemonstrateBuilderConfiguration("重载方法-快速模式", builder =>
            {
                return builder.WithAesEncryption(testPassword, AesMode.Fast);
            });

            DemonstrateBuilderConfiguration("重载方法-安全模式", builder =>
            {
                return builder.WithAesEncryption(testPassword, AesMode.Secure);
            });

            // 性能对比测试
            Console.WriteLine("\n🏃‍♂️ 构造器AES模式性能对比:");
            PerformanceComparison(testPassword);

            Console.WriteLine("\n✨ DeviceMessageBuilder AES模式配置功能演示完成！");
        }

        private static void DemonstrateBuilderConfiguration(string configName, Func<IDeviceMessageBuilder, IDeviceMessageBuilder> configure)
        {
            try
            {
                // 创建构造器并应用配置
                var builder = DeviceMessageBuilder.Create()
                    .WithHeader(version: 0x02, crcType: CRCTypeEnum.CRC32);

                builder = configure(builder);

                // 构建消息
                builder.WithMainDevice("DemoDevice", 0x01, config =>
                {
                    config.AddReading(100, reading =>
                    {
                        reading.AddState(1, $"测试数据 - {configName}", StateValueTypeEnum.String);
                        reading.AddState(2, DateTime.Now.Ticks, StateValueTypeEnum.Timestamp);
                        reading.AddState(3, 25.6f, StateValueTypeEnum.Float32);
                    });
                });

                // 构建加密的消息
                var encryptedHex = builder.BuildHex(compress: false, encrypt: true);

                Console.WriteLine($"  配置名称: {configName}");
                Console.WriteLine($"  加密消息长度: {encryptedHex.Length} 字符");
                Console.WriteLine($"  消息前缀: {encryptedHex.Substring(0, Math.Min(20, encryptedHex.Length))}...");

                // 验证解析
                var parser = DeviceMessageSerializerProvider.MessagePar;
                var parsedMessage = parser.Parser(encryptedHex);

                Console.WriteLine($"  解析成功: ✅ 设备ID = {parsedMessage.MainDevice.DID}");
                Console.WriteLine($"  解析状态数: {parsedMessage.MainDevice.Reading.ReadingArray.FirstOrDefault()?.State.StateArray.Length ?? 0}");

            }
            catch (Exception ex)
            {
                Console.WriteLine($"  配置名称: {configName}");
                Console.WriteLine($"  错误: ❌ {ex.Message}");
            }
        }

        private static void PerformanceComparison(string password)
        {
            const int iterations = 20;
            var testData = CreateTestData();

            Console.WriteLine("┌──────────────────┬──────────────┬──────────────┬──────────────┐");
            Console.WriteLine("│     配置模式     │  平均构建时间  │  平均解析时间  │    总时间    │");
            Console.WriteLine("├──────────────────┼──────────────┼──────────────┼──────────────┤");

            // 测试快速模式
            var (fastBuildTime, fastParseTime, fastTotalTime) = MeasureBuilderPerformance(
                builder => builder.WithFastAesEncryption(password),
                testData, iterations);

            Console.WriteLine($"│ 快速模式构造器   │{fastBuildTime,11:F3} ms │{fastParseTime,11:F3} ms │{fastTotalTime,11:F3} ms │");

            // 测试安全模式
            var (secureBuildTime, secureParseTime, secureTotalTime) = MeasureBuilderPerformance(
                builder => builder.WithSecureAesEncryption(password),
                testData, iterations);

            Console.WriteLine($"│ 安全模式构造器   │{secureBuildTime,11:F3} ms │{secureParseTime,11:F3} ms │{secureTotalTime,11:F3} ms │");

            // 计算性能差异
            var buildSpeedup = secureBuildTime / fastBuildTime;
            var parseSpeedup = secureParseTime / fastParseTime;
            var totalSpeedup = secureTotalTime / fastTotalTime;

            Console.WriteLine("├──────────────────┼──────────────┼──────────────┼──────────────┤");
            Console.WriteLine($"│ 性能差异         │{buildSpeedup,11:F1}x     │{parseSpeedup,11:F1}x     │{totalSpeedup,11:F1}x     │");
            Console.WriteLine("└──────────────────┴──────────────┴──────────────┴──────────────┘");

            Console.WriteLine($"\n💡 性能分析:");
            Console.WriteLine($"   - 快速模式构造器比安全模式快约 {totalSpeedup:F1} 倍");
            Console.WriteLine($"   - 构建阶段性能差异: {buildSpeedup:F1}x");
            Console.WriteLine($"   - 解析阶段性能差异: {parseSpeedup:F1}x");
        }

        private static (double buildTime, double parseTime, double totalTime) MeasureBuilderPerformance(
            Func<IDeviceMessageBuilder, IDeviceMessageBuilder> configure,
            (string deviceId, byte deviceType, Action<DeviceInfoBuilder> config) testData,
            int iterations)
        {
            var sw = Stopwatch.StartNew();

            // 测量构建时间
            sw.Restart();
            string? encryptedHex = null;
            for (int i = 0; i < iterations; i++)
            {
                var builder = DeviceMessageBuilder.Create()
                    .WithHeader(version: 0x02, crcType: CRCTypeEnum.CRC32);

                builder = configure(builder);
                builder.WithMainDevice(testData.deviceId, testData.deviceType, testData.config);

                encryptedHex = builder.BuildHex(compress: false, encrypt: true);
            }
            var buildTime = sw.ElapsedMilliseconds / (double)iterations;

            // 测量解析时间
            sw.Restart();
            var parser = DeviceMessageSerializerProvider.MessagePar;
            for (int i = 0; i < iterations; i++)
            {
                parser.Parser(encryptedHex!);
            }
            var parseTime = sw.ElapsedMilliseconds / (double)iterations;

            var totalTime = buildTime + parseTime;

            return (buildTime, parseTime, totalTime);
        }

        private static (string deviceId, byte deviceType, Action<DeviceInfoBuilder> config) CreateTestData()
        {
            return ("PerformanceDevice", 0x01, config =>
            {
                for (int i = 0; i < 5; i++)
                {
                    config.AddReading((short)(i * 100), reading =>
                    {
                        reading.AddState(1, $"性能测试数据 {i}", StateValueTypeEnum.String);
                        reading.AddState(2, i * 1000, StateValueTypeEnum.Int32);
                        reading.AddState(3, i * 3.14f, StateValueTypeEnum.Float32);
                        reading.AddState(4, i % 2 == 0, StateValueTypeEnum.Bool);
                    });
                }
            }
            );
        }
    }
}